package com.ecnu.jiagou.damai.controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.ecnu.jiagou.damai.config.AlipayConfig;
import com.ecnu.jiagou.damai.utils.RedisUtil;
import com.ecnu.jiagou.damai.utils.WebSocket;
import com.ecnu.jiagou.damai.service.OrderService;
import com.ecnu.jiagou.damai.utils.UUIDUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/alipay")
public class PayController {

    private static Logger log = LoggerFactory.getLogger(PayController.class);

    @Autowired
    private OrderService orderService;

    @Autowired
    private WebSocket webSocket;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 支付接口
     * @param request(userid,ticketid,rows,cols,amount,personid,addressid) //还需要amount参数
     * @param response
     * @throws IOException
     */
    @RequestMapping("/pay")
    public void payController(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
  
      //获得初始化的AlipayClient  
      AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);       
      //设置请求参数
      AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
      alipayRequest.setReturnUrl(AlipayConfig.return_url);
      alipayRequest.setNotifyUrl(AlipayConfig.notify_url);


      String userid = new String(request.getParameter("userid").getBytes("ISO-8859-1"),"UTF-8");
      String ticketid = new String(request.getParameter("ticketid").getBytes("ISO-8859-1"),"UTF-8");
      String rows = new String(request.getParameter("rows").getBytes("ISO-8859-1"),"UTF-8");
      String cols = new String(request.getParameter("cols").getBytes("ISO-8859-1"),"UTF-8");
      String personid = new String(request.getParameter("personid").getBytes("ISO-8859-1"),"UTF-8");
      String addressid = new String(request.getParameter("addressid").getBytes("ISO-8859-1"),"UTF-8");
      if(personid == null || personid.equals("")){
          personid = "0";
      }
      if(addressid == null || addressid.equals("")){
          addressid = "0";
      }


      /*
      session.setAttribute("userid",userid);
      session.setAttribute("ticketid",ticketid);
      session.setAttribute("rows",rows);
      session.setAttribute("cols",cols);
       */

      String orderid = UUIDUtil.uuid().toUpperCase();
      //request.setAttribute("out_trade_no", orderid);
      //商户订单号，商户网站订单系统中唯一订单号，必填
      //System.out.println(orderid);
      String out_trade_no = new String(orderid.getBytes("ISO-8859-1"),"UTF-8");
      log.info("out_trade_no",out_trade_no);
      //付款金额，必填
      String total_amount = new String(request.getParameter("amount").getBytes("ISO-8859-1"),"UTF-8");
      //订单名称，必填
      String subject = new String("Pay to damai".getBytes("ISO-8859-1"),"UTF-8");
      //商品描述，可空
      String body = new String("Buy Tickets".getBytes("ISO-8859-1"),"UTF-8");

      redisUtil.set(out_trade_no,userid+";"+ticketid+";"+personid+";"+addressid+";"+rows+";"+cols);

      redisUtil.expire(out_trade_no,10*60);

      alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
          + "\"total_amount\":\""+ total_amount +"\","
          + "\"subject\":\""+ subject +"\","
          + "\"body\":\""+ body +"\","
          + "\"timeout_express\":\"2m\","
          + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"); 
     
      //请求 
      String form=""; 
      try {  
        form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单 
      } catch (AlipayApiException e) { 
        e.printStackTrace();
      }
      response.setContentType("text/html;charset=" + AlipayConfig.CHARSET); 
      response.getWriter().write(form);//直接将完整的表单html输出到页面 
      response.getWriter().flush();  
      response.getWriter().close();
    }

    //同步回调处理方法
    @GetMapping("/return")
    //@ResponseBody
    public String return_url(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {
        log.info("进入return请求");
        //获取支付宝GET过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        //String userid = new String(request.getParameter("userid").getBytes("ISO-8859-1"),"UTF-8");
        //String ticketid = new String(request.getParameter("ticketid").getBytes("ISO-8859-1"),"UTF-8");
        //String rows = new String(request.getParameter("rows").getBytes("ISO-8859-1"),"UTF-8");
        //String cols = new String(request.getParameter("cols").getBytes("ISO-8859-1"),"UTF-8");
        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
        log.info("return out_trade_no",out_trade_no);
        String parameters = redisUtil.get(out_trade_no).toString();
        String []splits = parameters.split(";");

        String rows = "";
        String cols = "";
        String userid = splits[0];
        String ticketid = splits[1];
        String personid = splits[2];
        String addressid = splits[3];
        if(splits.length != 4){
            rows = splits[4];
            cols = splits[5];
        }

        //redisUtil.get()
        log.info("userid" + userid);
        log.info("ticketid" + ticketid);
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        //计算得出通知验证结果
        //webSocket.sendMessage("支付成功");
        //orderService.updateTicket(ticketid, rows, cols);
        //orderService.addOrder(Long.parseLong(userid), ticketid, rows, cols);
        boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");

        //log.info("test result" + verify_result);
        String flag = redisUtil.get(out_trade_no+userid).toString();
        if(flag == null || flag.equals("")){
            flag = "false";
        }
        if(verify_result && flag.equals("true")){//验证成功
            //请在这里加上商户的业务逻辑程序代码
            //boolean flag = orderService.updateTicket(ticketid, rows, cols);
            //orderService.addOrder(Long.parseLong(userid), ticketid, personid,addressid, rows, cols);
            log.info("i am coming =============>");
            //webSocket.sendMessage("支付成功");
            return "success";//跳转到订单信息页面

        }else{
            //webSocket.sendMessage("支付失败");
            return "error";//跳转到首页
        }
    }

    //异步回调处理方法
    //@ResponseBody
    @PostMapping("/notify")
    public String notify_url(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {
        log.info("进入该notify请求");
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        //商户订单号

        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

        log.info("notify out_trade_no",out_trade_no);
        String parameters = redisUtil.get(out_trade_no).toString();
        String []splits = parameters.split(";");
        String userid = splits[0];
        String ticketid = splits[1];
        String personid = splits[2];
        String addressid = splits[3];
        String rows = "";
        String cols = "";
        if(splits.length != 4){
            rows = splits[4];
            cols = splits[5];
        }

        log.info("userid" + userid);
        log.info("ticketid" + ticketid);

        //交易状态
        String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

        //计算得出通知验证结果
        boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");

        if(verify_result){//验证成功

            boolean flag1 = orderService.updateTicket(ticketid, rows, cols);
            boolean flag2 = false;
            log.info("修改座位信息成功与否"+flag1);
            if(flag1){
                flag2 = orderService.addOrder(Long.parseLong(userid), ticketid, personid,addressid, rows, cols);
            }else{
                log.info("支付失败");
                webSocket.send(userid,"支付失败");
                redisUtil.set(out_trade_no + userid,"false",3*60);
                return "error";
            }

            /*
            //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
            if(trade_status.equals("TRADE_FINISHED")){
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理，不执行商户的业务程序

                //注意：
                //如果签约的是可退款协议，退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
                //如果没有签约可退款协议，那么付款完成后，支付宝系统发送该交易状态通知。
            } else if (trade_status.equals("TRADE_SUCCESS")){
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理，不执行商户的业务程序

                //注意：
                //如果签约的是可退款协议，那么付款完成后，支付宝系统发送该交易状态通知。
            }
            */

            if(flag1 && flag2){
                webSocket.send(userid,"支付成功");
                redisUtil.set(out_trade_no + userid,"true",3*60);
                //webSocket.sendMessage("支付成功"+","+userid);
                return "success";//跳转到订单信息页面
            }else{
                webSocket.send(userid,"支付失败");
                //redisUtil.set(out_trade_no + userid,"false",3*60);
                //webSocket.sendMessage("支付失败"+","+userid);
                return "error";
            }
            //return "redirect:/#/";

        }else{//验证失败
            webSocket.send(userid,"支付失败");
            //webSocket.sendMessage("支付失败"+","+userid);
            return "error";//跳转到首页
            //return "redirect:/#/";
        }
    }

}
